package io.github.uicdb.et;

import io.github.uicdb.et.register.ElementalObject;
import io.github.uicdb.et.register.IElementalGetter;
import net.minecraft.core.Holder;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.AABB;
import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.entity.living.MobEffectEvent;
import net.neoforged.neoforge.registries.DeferredRegister;
import org.jetbrains.annotations.NotNull;
import org.w3c.dom.Attr;

public class ModEffects {
    private static final DeferredRegister<MobEffect> EFFECTS = DeferredRegister.create(BuiltInRegistries.MOB_EFFECT, ElementalTheory.MODID);
    public static final Holder<MobEffect> INJURE = EFFECTS.register("injure", () -> new InjureEffect(MobEffectCategory.HARMFUL, 0));//治疗范围玩家

    public static final Holder<MobEffect> WATER_RECOVER = EFFECTS.register("water_recover", () -> new RecoverEffect(MobEffectCategory.BENEFICIAL, 0));//治疗范围玩家

 public static final Holder<MobEffect> SERIOUS_INJURY = EFFECTS.register("serious_injury", () -> new Effect( MobEffectCategory.HARMFUL,0)
            .addAttributeModifier(Attributes.ARMOR,ResourceLocation.fromNamespaceAndPath(ElementalTheory.MODID,"serious_injury_armor"),-1, AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL)
            .addAttributeModifier(Attributes.MAX_HEALTH,ResourceLocation.fromNamespaceAndPath(ElementalTheory.MODID,"serious_injury_health"),-0.8, AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL)
    );

    public static void init(IEventBus bus) {
        EFFECTS.register(bus);
    }

    public static class Effect extends MobEffect {

        public Effect(MobEffectCategory category, int color) {
            super(category, color);
        }

        protected Effect(MobEffectCategory category, int color, ParticleOptions particle) {
            super(category, color, particle);
        }

    }
    public static class InjureEffect extends MobEffect{
        protected InjureEffect(MobEffectCategory category, int color) {
            super(category, color);
        }
    }
    public static class RecoverEffect extends MobEffect {

        public RecoverEffect(MobEffectCategory category, int color) {
            super(category, color);
        }

        public boolean applyEffectTick(LivingEntity livingEntity, int amplifier) {
            livingEntity.level().getEntitiesOfClass(Player.class, AABB.ofSize(livingEntity.position(), 10, 4, 10))
                    .forEach(player -> player.heal((1 + amplifier)));

            return true;
        }

        public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) {
            return duration % 20 == 0;
        }
    }

    public static class RockFluidEffect extends MobEffect {

        public RockFluidEffect(MobEffectCategory category, int color) {
            super(category, color);
        }

        public boolean applyEffectTick(LivingEntity livingEntity, int amplifier) {
            if (livingEntity.getDeltaMovement().y >= 0 && !livingEntity.isFallFlying())
                livingEntity.heal((float) amplifier / 2f);
            else
                livingEntity.hurt(ModElements.EARTH.getElemental().getDamageSource(livingEntity.level(), livingEntity.getLastAttacker()), (float) amplifier / 2f);
            return true;
        }

        public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) {
            return duration % 20 == 0;
        }
    }

    public static class RockFluidEffectShadow extends MobEffect {

        public RockFluidEffectShadow(MobEffectCategory category, int color) {
            super(category, color);
        }

        public boolean applyEffectTick(LivingEntity livingEntity, int amplifier) {
            if (livingEntity.getDeltaMovement().y < 0 || livingEntity.isFallFlying())
                livingEntity.heal((float) amplifier / 2f);
            else
                livingEntity.hurt(ModElements.EARTH.getElemental().getDamageSource(livingEntity.level(), livingEntity.getLastAttacker()), (float) amplifier / 2f);
            return true;
        }

        public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) {
            return duration % 20 == 0;
        }
    }

    public static class DotEffect extends MobEffect {
        final ElementalObject object;
        float baseDamage = 1;
        protected DotEffect(int color, ElementalObject object) {
            super(MobEffectCategory.HARMFUL, color);
            this.object = object;
        }
        protected DotEffect(int color, ElementalObject object,float baseDamage) {
            super(MobEffectCategory.HARMFUL, color);
            this.object = object;
            this.baseDamage = baseDamage;
        }

        public boolean applyEffectTick(LivingEntity livingEntity, int amplifier) {
            livingEntity.hurt(ModElements.EARTH.getElemental().getDamageSource(livingEntity.level(), livingEntity.getLastAttacker()), baseDamage*(1 + amplifier) );
            return true;
        }

        public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) {
            return duration % 20 == 0;
        }
    }




    @EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME)
    private static class ElementEffectHandler {
        @SubscribeEvent(priority = EventPriority.LOW)
        public static void onExpired(MobEffectEvent.Expired event) {
            onRemoveEffect(event.getEffectInstance(), event.isCanceled(), event.getEntity());
        }

        @SubscribeEvent(priority = EventPriority.LOW)
        public static void onRemove(MobEffectEvent.Remove event) {
            onRemoveEffect(event.getEffectInstance(), event.isCanceled(), event.getEntity());
        }

        private static void onRemoveEffect(MobEffectInstance event, boolean isCanceled, LivingEntity entity) {
            if (event == null || isCanceled) return;

        }
    }

}
